assert_(not (self.closed), 'Iterator read after closed')
v = self.iterator.next()
if self.check_start_response is not None:
assert_(self.check_start_response, 'The application returns and we started iterating over its body, but start_response has not yet been called')
self.check_start_response = None
return v
def close(self):
self.closed = True
if hasattr(self.original_iterator, 'close'):
self.original_iterator.close()
def __del__(self):
if not self.closed:
sys.stderr.write('Iterator garbage collected without being closed')
assert_(self.closed, 'Iterator garbage collected without being closed')
def check_environ(environ):
assert_(type(environ) is DictType, 'Environment is not of the right type: %r (environment: %r)' % (type(environ), environ))
for key in [
'REQUEST_METHOD',
'SERVER_NAME',
'SERVER_PORT',
'wsgi.version',
'wsgi.input',
'wsgi.errors',
'wsgi.multithread',
'wsgi.multiprocess',
'wsgi.run_once']:
assert_(key in environ, 'Environment missing required key: %r' % (key,))
for key in [
'HTTP_CONTENT_TYPE',
'HTTP_CONTENT_LENGTH']:
assert_(key not in environ, 'Environment should not have the key: %s (use %s instead)' % (key, key[5:]))
if 'QUERY_STRING' not in environ:
warnings.warn('QUERY_STRING is not in the WSGI environment; the cgi module will use sys.argv when this variable is missing, so application errors are more likely', WSGIWarning)
for key in environ.keys():
if '.' in key:
continue
assert_(type(environ[key]) is StringType, 'Environmental variable %s is not a string: %r (value: %r)' % (key, type(environ[key]), environ[key]))
assert_(type(environ['wsgi.version']) is TupleType, 'wsgi.version should be a tuple (%r)' % (environ['wsgi.version'],))
assert_(environ['wsgi.url_scheme'] in ('http', 'https'), 'wsgi.url_scheme unknown: %r' % environ['wsgi.url_scheme'])
check_input(environ['wsgi.input'])
check_errors(environ['wsgi.errors'])
if environ['REQUEST_METHOD'] not in ('GET', 'HEAD', 'POST', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'):
assert_(environ.has_key('PATH_INFO'), "One of SCRIPT_NAME or PATH_INFO are required (PATH_INFO should at least be '/' if SCRIPT_NAME is empty)")
assert_(environ.get('SCRIPT_NAME') != '/', "SCRIPT_NAME cannot be '/'; it should instead be '', and PATH_INFO should be '/'")
def check_input(wsgi_input):
for attr in [
'read',
'readline',
'readlines',
'__iter__']:
assert_(hasattr(wsgi_input, attr), "wsgi.input (%r) doesn't have the attribute %s" % (wsgi_input, attr))
def check_errors(wsgi_errors):
for attr in [
'flush',
'write',
'writelines']:
assert_(hasattr(wsgi_errors, attr), "wsgi.errors (%r) doesn't have the attribute %s" % (wsgi_errors, attr))
def check_status(status):
assert_(type(status) is StringType, 'Status must be a string (not %r)' % status)
status_code = status.split(None, 1)[0]
assert_(len(status_code) == 3, 'Status codes must be three characters: %r' % status_code)
status_int = int(status_code)
assert_(status_int >= 100, 'Status code is invalid: %r' % status_int)
if len(status) < 4 or status[3] != ' ':
warnings.warn('The status string (%r) should be a three-digit integer followed by a single space and a status explanation' % status, WSGIWarning)
def check_headers(headers):
assert_(type(headers) is ListType, 'Headers (%r) must be of type list: %r' % (headers, type(headers)))
header_names = { }
for item in headers:
assert_(type(item) is TupleType, 'Individual headers (%r) must be of type tuple: %r' % (item, type(item)))
assert_(len(item) == 2)
(name, value) = item
assert_(name.lower() != 'status', 'The Status header cannot be used; it conflicts with CGI script, and HTTP status is not given through headers (value: %r).' % value)
header_names[name.lower()] = None
if '\n' not in name:
pass
assert_(':' not in name, "Header names may not contain ':' or '\\n': %r" % name)
assert_(0, 'Content-Type header found in a %s response, which must not return content.' % code)
continue
if code not in NO_MESSAGE_BODY:
assert_(0, 'No Content-Type header found in headers (%s)' % headers)
def check_exc_info(exc_info):
if not exc_info is None:
pass
assert_(type(exc_info) is type(()), 'exc_info (%r) is not a tuple: %r' % (exc_info, type(exc_info)))
def check_iterator(iterator):
assert_(not isinstance(iterator, str), 'You should not return a string as your application iterator, instead return a single-item list containing that string.')